"use strict";
/**
 * @ Author: Yoann Meclot. MSay2
 * @ Created on: 2020-07-13 08:20:15
 * @ Modified on: 2020-09-29 10:52:07
 *
 * @version 1.8
 */
/**
 * Copyright (c) 2020 MSay2, Yoann Meclot - ArrayList.ts
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayList = exports.Arrays = exports.List = void 0;
/**
 * The Entry class is a mean to log a key associated with its value.
 *
 * The Entry class is used by the EntryIterable class to obtain each entry to the array
 * and thus obtain each values in a loop.
 *
 * @class Entry<K,V>
 * @version 1.4
 * @since 1.4
 */
class Entry {
}
/**
 * The EntryIterable class is a mean to reiterate the entries to the array.
 *
 * It allows to you obtain eachs values of eachs entries of the array
 * with its respectives methods Entry.getValue.
 *
 * @class EntryIterable
 * @implements {Iterable}
 * @version 1.2
 * @since 1.5
 */
class EntryIterable {
    constructor(values, size) {
        this.values = [];
        this.index = -1;
        this.size = 0;
        this.values = values;
        this.size = size;
    }
    [Symbol.iterator]() {
        return {
            next: () => {
                this.index++;
                if (this.index < this.size) {
                    return {
                        value: {
                            getValue: () => this.values[this.index],
                            isLastData: () => {
                                if (this.index == this.size - 1)
                                    return true;
                                return false;
                            },
                            isFirstData: () => {
                                if (this.index == 0)
                                    return true;
                                return false;
                            }
                        },
                        done: false
                    };
                }
                return {
                    value: null,
                    done: true
                };
            }
        };
    }
}
/**
 * This class provides a way to handle an array containing ​​specific values to cast.
 *
 * @class List
 * @version 1.1
 * @since 1.0
 */
class List {
}
exports.List = List;
/**
 * This class allows you to create and join your primitive array in the ArrayList class.
 *
 * @class Arrays
 * @version 1.0
 * @since 1.6
 */
class Arrays {
    /**
     * Create and join your primitive array in the ArrayList class.
     *
     * @param array Corresponding to your primitive array.
     * @type {List<B>}
     * @since 1.0
     */
    static asList(array) {
        return new ArrayList(array);
    }
}
exports.Arrays = Arrays;
/**
 * This class provides a way to handle an array containing ​​specific values to cast.
 *
 * @class ArrayList
 * @version 1.2
 * @since 1.0
 */
class ArrayList extends List {
    /**
     * Default constructor.
     *
     * You can init a array ArrayList by your intern array, leave empty to simply
     * create a new array.
     *
     * @param array The array to be joined.
     * @version 1.0
     * @since 1.0
     */
    constructor(array) {
        super();
        this.values = [];
        this.length = 0;
        if (array != undefined && array != null) {
            this.values = array;
            this.length = array.length;
        }
    }
    add(value) {
        this.values[this.length] = value;
        this.ensureIncrementSize(1);
    }
    addAt(index, value) {
        let otherValues = [];
        for (let i = 0, v = 0, e = 0; i < this.length + 1; i++) {
            if (i == index) {
                otherValues[v++] = value;
            }
            else {
                otherValues[v++] = this.values[e++];
            }
        }
        this.ensureIncrementSize(1);
        this.values = otherValues;
        otherValues = null;
    }
    addAll(...lists) {
        for (let list of lists) {
            let size = list.size();
            if (size > 0) {
                for (let entry of list.entries()) {
                    this.add(entry.getValue());
                }
            }
        }
    }
    get(index) {
        for (let i = 0; i < this.length; i++) {
            if (index == i) {
                return this.values[i];
            }
        }
        return null;
    }
    indexOf(value) {
        for (let i = 0; i < this.length; i++) {
            if (this.values[i] == value) {
                return i;
            }
        }
        return -1;
    }
    contains(value) {
        return this.indexOf(value) >= 0;
    }
    containsInstanceOf(objectName, forAll) {
        if (objectName == null) {
            return false;
        }
        if (this.size() > 0) {
            let isFind = false;
            for (let entry of this.entries()) {
                if (entry.getValue().constructor.name == objectName) {
                    if (!forAll) {
                        return true;
                    }
                    isFind = true;
                }
            }
            return isFind;
        }
        return false;
    }
    containsOnlyInstanceOf(objectName) {
        if (objectName == null) {
            return false;
        }
        if (this.size() > 0) {
            let quantity = 0;
            for (let entry of this.entries()) {
                if (entry.getValue().constructor.name == objectName) {
                    quantity++;
                }
            }
            return quantity == this.size();
        }
        return false;
    }
    remove(index) {
        let otherValues = [];
        for (let i = 0, v = 0; i < this.length; i++) {
            if (index == i) {
                continue;
            }
            otherValues[v++] = this.values[i];
        }
        this.values = otherValues;
        this.ensureDecrementSize(1);
        otherValues = null;
    }
    removeQuantity(start, count) {
        for (let i = 0; i < count; i++) {
            for (let e = 0; e < this.length; e++) {
                if (e == start) {
                    this.remove(e);
                    return;
                }
            }
        }
    }
    entries() {
        return new EntryIterable(this.values, this.length);
    }
    clear() {
        for (let i = 0; i < this.length; i++) {
            this.values[i] = null;
        }
        this.length = 0;
        this.values = [];
    }
    clearMemory() {
        this.values.length = 0;
        this.length = 0;
    }
    isEmpty() {
        return this.length == 0;
    }
    size() {
        return this.length;
    }
    toArray() {
        return this.values;
    }
    /**
     * Ensures the incrementation of the size to update the current size of the array
     *
     * @param value incremented value
     * @type {void}
     * @since 1.0
     */
    ensureIncrementSize(value) {
        this.length += value;
    }
    /**
     * Ensures the decrementation of the size to update the current size of the array
     *
     * @param value Decremented value
     * @type {void}
     * @since 1.0
     */
    ensureDecrementSize(value) {
        this.length -= value;
    }
}
exports.ArrayList = ArrayList;
//# sourceMappingURL=ArrayList.js.map